﻿using CommandLine;
using FileDownloader;
using log4net;
using NugetDownloader.Spider;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NugetDownloaderCommandline
{
    class Program
    {
        //NugetDownloaderCommandline.exe -s 4 -e 11 -q "asdf sf"
        static void Main(string[] args)
        {
            CommandLine.Parser.Default.ParseArguments<Options>(args)
            .WithParsed<Options>(opts => {
                Console.WriteLine($"start={opts.Start}, end={opts.End}, query={opts.Query}, prerel={opts.Prerel}");
                download(opts.Start, opts.End, opts.Query, opts.Prerel);
            })
            .WithNotParsed<Options>((errs) => {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(errs);
                Console.ResetColor();
            });
            
            Console.ReadLine();
        }

        static ILog log = LogManager.GetLogger(typeof(Program));
        static object locker = new object();
        static int finishCount = 0;
        static int total = 0;

        static async Task download(int start, int end, string query, bool prerel)
        {
            var spider = new Spider();


            for (int i = start; i < end; i++)
            {
                try
                {
                    reportStart(i);
                    var result = await spider.GetPackageDownloadUrls(query, i, prerel);
                    lock (locker)
                    {
                        total += result.Count;
                    }
                    startDownload(result);
                }
                catch (Exception ex)
                {
                    log.Error("", ex);
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("[ERROR] {0}", ex);
                    Console.ResetColor();
                }

            }
        }

        static async Task startDownload(List<string> urls)
        {
            foreach (var url in urls)
            {
                var fileDownloader = new FileDownloader.FileDownloader();
                fileDownloader.DownloadProgressChanged += FileDownloader_DownloadProgressChanged;
                fileDownloader.DownloadFileCompleted += FileDownloader_DownloadFileCompleted;

                var filename = url.Substring("https://www.nuget.org/api/v2/package/".Length).Replace("/", ".") + ".nupkg.dl";
                filename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Downloads", filename);
                var dir = Path.GetDirectoryName(filename);
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
                if (!File.Exists(filename.Substring(0, filename.Length - 3)))
                {
                    if (File.Exists(filename))
                    {
                        File.Delete(filename);
                    }
                    fileDownloader.DownloadFileAsync(new Uri(url), filename);
                    //Console.WriteLine("Start: {0}",url);
                }
                else
                {
                    Console.WriteLine("Exist:{0}", filename);
                }
            }

        }

        static void FileDownloader_DownloadFileCompleted(object sender, DownloadFileCompletedArgs e)
        {
            System.Threading.Interlocked.Increment(ref finishCount);
            reportFinish(sender as IFileDownloader, e);
            try
            {
                var d = sender as FileDownloader.FileDownloader;
                if (d.destinationFileName?.EndsWith(".dl") == true)
                {
                    var newFileName = d.destinationFileName.Substring(0, d.destinationFileName.Length - 3);
                    File.Move(d.destinationFileName, newFileName);
                }

            }
            catch (Exception ex)
            {
                log.Error("", ex);
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("[ERROR] {0}", ex);
                Console.ResetColor();
            }
        }

        static void FileDownloader_DownloadProgressChanged(object sender, DownloadFileProgressChangedArgs e)
        {
            reportStatus(sender as IFileDownloader, e);
        }


        static void reportStart(int page)
        {
            Console.WriteLine($"正在下载第{page}页");
        }

        static void reportStatus(IFileDownloader downloader, DownloadFileProgressChangedArgs e)
        {
            //if (downloaders.ContainsKey(downloader))
            //{
            //    uiInvoke(() =>
            //    {
            //        downloaders[downloader].SubItems[2].Text = DownloadStatus.Downloading.ToString();
            //        downloaders[downloader].SubItems[1].Text = e.ProgressPercentage.ToString();
            //        downloaders[downloader].BackColor = Color.LightGreen;
            //    });
            //}
        }

        static void reportFinish(IFileDownloader downloader, DownloadFileCompletedArgs e)
        {
            //if (downloaders.ContainsKey(downloader))
            //{
            //    //uiInvoke(() =>
            //    //{
            //    //    downloaders[downloader].SubItems[2].Text = DownloadStatus.Finish.ToString();
            //    //    this.label1.Text = $"{finishCount}/{total}";
            //    //    downloaders[downloader].BackColor = Color.LightGray;
            //    //});
            //}
            Console.WriteLine("DownloadFinish:{0}, {1}/{2}", e.FileName, finishCount, total);
        }
    }
}
